<!-- 预览文件，支持docx、xlsx、pdf、图片 -->
<script setup lang="ts">
import Excel from './component/Excel.vue'
import NotSupported from './component/NotSupported.vue'
import Pdf from './component/Pdf.vue'
import Picture from './component/Picture.vue'
import Word from './component/Word.vue'

import { computed, ref, watch } from 'vue'

import { message } from '@/utils/message'
import { downloadFile, downloadFileRaw } from './util'

const props = defineProps({
  /** 文件名 */
  fileName: String,
  /** 链接地址 */
  filePath: String,
  /** 预览高度 */
  viewHeight: {
    type: Number,
    default: 239,
  },
})
const visible = defineModel('visible', { type: Boolean })

const loading = ref(true)
const fileData = ref<Blob>()
const hasError = ref(false)
const fileSuffix = computed(() => {
  return props.fileName.split('.').pop()
})

/** 关闭预览 */
const closePreview = () => {
  visible.value = false
  loading.value = true
  fileData.value = null
}

/** 渲染完成 */
function renderedHandler() {
  loading.value = false
}

/** 渲染失败 */
function errorHandler() {
  loading.value = false
  hasError.value = true
}

/**
 * 下载文件
 */
const download = () => {
  downloadFile({
    filePath: props.filePath,
    fileName: props.fileName,
  }).then(() => {
    message('下载成功！', { type: 'success' })
  })
}

watch(visible, (v) => {
  loading.value = v
  hasError.value = false

  if (v) {
    downloadFileRaw({
      filePath: props.filePath,
      fileName: props.fileName,
    }).then((data) => {
      fileData.value = data
    })
  }
})
</script>

<template>
  <el-card v-if="visible" shadow="never" class="fixed inset-0 z-[1002]">
    <template #header>
      <div class="flex justify-between">
        <h1 class="font-medium">{{ props.fileName }}</h1>
        <div>
          <!-- NOTE: 不能用el-button，表单disabled时，下层的el-button全部都disabled -->
          <button class="el-button el-button--primary" @click.prevent="download">下载</button>
          <button class="el-button" @click.prevent="closePreview">返回</button>
        </div>
      </div>
    </template>
    <!-- 渲染失败 -->
    <div
      v-if="hasError"
      :style="`height: calc(100vh - ${props.viewHeight}px) `"
      class="flex items-center justify-center"
    >
      暂不支持预览
    </div>
    <!-- 渲染成功 -->
    <div v-loading="loading" :style="`height: calc(100vh - ${props.viewHeight}px) `">
      <Pdf
        v-if="/pdf/.test(fileSuffix)"
        :fileData="fileData"
        :fileName="props.fileName"
        :renderedHandler="renderedHandler"
        :errorHandler="errorHandler"
      />
      <Word
        v-else-if="/docx/.test(fileSuffix)"
        :fileData="fileData"
        :fileName="props.fileName"
        :renderedHandler="renderedHandler"
        :errorHandler="errorHandler"
      />
      <Excel
        v-else-if="/xlsx/.test(fileSuffix)"
        :fileData="fileData"
        :fileName="props.fileName"
        :renderedHandler="renderedHandler"
        :errorHandler="errorHandler"
      />
      <Picture
        v-else-if="/(jpg|png|jpeg|gif|bmp|webp)$/i.test(fileSuffix)"
        :filePath="filePath"
        :fileName="props.fileName"
        :renderedHandler="renderedHandler"
        :errorHandler="errorHandler"
      />
      <NotSupported
        v-else
        :filePath="filePath"
        :fileName="props.fileName"
        :renderedHandler="renderedHandler"
        :errorHandler="errorHandler"
      />
    </div>
  </el-card>
</template>

<style scoped>
.el-card__header h1 {
  font-size: 20px;
}
</style>
